package com.hb.B_面向对象.A_类与继承

/**
 * 由于内部类可以继承一个与外部类无关的类，所以这保证了内部类的独立性，我们可以用它的这个特性
 * 来尝试解决多继承的问题。
 */
fun main() {
    OuterKotlin().InnerKotlin().printName()
}

/**
 * 众所周知，在java中，我们可以在内部类的语法上增加一个static关键词，把它变成一个嵌套类
 * 然而，Kotlin则是相反的思路，默认是一个嵌套类，必须加上inner关键字才是一个内部类，也就
 * 是说可以把静态的内部类看成是嵌套类。
 *
 * 内部类和嵌套类有明显的差别，具体体现在：内部类包含着对其外部类实例的引用，在内部类中我们可以
 * 使用外部类中的属性。比如上面的例子中的name属性；而嵌套类不包含对其外部类实例的引用，所以他无法
 * 调用其外部类的属性。
 */
class OuterKotlin{
    val name="truely Kotlin's inner class syntax"
    inner class InnerKotlin{
        fun printName(){
            println("the name is $name")
        }
    }
}

/**
 * 骡马问题：
 *  可以发现：
 *      1. 我们可以在一个类内部定义多个内部类，每个内部类的实例都有自己的独立状态，他们与外部对象的信息相互独立
 *      2. 通过让内部类HorseC、DonkeyC分别继承Horse和Donkey这两个外部类，我们就可以在Mule类中定义他们的实例
 *      对象，从而获得了Horse和Donkey两者不同的状态和行为
 *      3. 我们可以利用private修饰内部类，使得其他类都不能访问内部类，具有非常良好的封装性
 * */
open class Horse{
    //马
    fun runFast(){
        println("Horse runFast")
    }
}
open class Donkey{
    //马
    fun doLongtimeThing(){
        println("Donkey doLongtimeThing")
    }
}

class Mute{
    private inner class  HorseC:Horse()
    private inner class  DonkeyC:Donkey()

    fun runFast(){
        HorseC().runFast()
    }

    fun doLongtimeThing(){
        DonkeyC().doLongtimeThing()
    }
}



